package org.hismig.migration.executor.ext;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import org.hismig.cfg.ExtExecutor;
import org.hismig.migration.Context;
import org.hismig.migration.result.ResultInfo;
import org.hismig.partition.IDynamicPartition;
import org.hismig.utils.CheckTool;
import org.hismig.utils.JDBCTool;
import org.hismig.utils.StringTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @declare: //TODO <br />
 *           This class created by Vansion.Hopihit on 2012-07-04 <br />
 *           <a href="mailto:vansionhopihit@gmail.com">Contact Me</a>
 * @version 1.0
 * @author Vansion.Hopihit
 * 
 */
public class SqlExecutor implements IExtExecutor {

	private ExtExecutor extExecutor; // cfg

	private DataSource dataSource;
	private IDynamicPartition dynamicPartition;
	private String name;

	private static final String KEY_SQL = "sql";

	private static Logger logger = LoggerFactory.getLogger(SqlExecutor.class);

	@Override
	public ResultInfo execute(Context context) {

		ResultInfo resultInfo = new ResultInfo(name);

		DataSource ds;
		if (null != dynamicPartition) {
			try {
				ds = dynamicPartition.getDataSource(context);
			} catch (SQLException e) {
				resultInfo.addException(e);
				return resultInfo;
			}
		} else {
			ds = dataSource;
		}
		CheckTool.checkNotNull(ds);

		int step = 0;

		String sql_src = extExecutor.getParamByName(KEY_SQL);
		CheckTool.checkNotEmpty(sql_src);

		step++;
		logger.debug(String.format("[step-%s]Get sql_src : %s", new Object[]{
				step, sql_src}));

		String sql_ready = context.getParsedVariable(sql_src);

		resultInfo.setSql(sql_ready);

		step++;
		logger.debug(String.format("[step-%s]Get sql_ready : %s", new Object[]{
				step, sql_ready}));

		Connection conn = null;
		Statement stmt = null;

		try {
			resultInfo.setStartTime(System.currentTimeMillis());
			conn = ds.getConnection();
			stmt = conn.createStatement();
			resultInfo.setEffectCount(stmt.executeUpdate(sql_ready));
			resultInfo.setEndTime(System.currentTimeMillis());
			logger.info(String.format(
					"execute sql successful (effectCount:%s) (cost:%sms)",
					new Object[]{resultInfo.getEffectCount(),
							resultInfo.getExecuteTime()}));
		} catch (SQLException e) {
			resultInfo.setEndTime(System.currentTimeMillis());
			resultInfo.addException(e);
			logger.error(e.toString(), e);
		} finally {
			JDBCTool.closeQuietly(stmt);
			JDBCTool.closeQuietly(conn);
		}

		return resultInfo;
	}

	@Override
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	@Override
	public void setDynamicPartition(IDynamicPartition dynamicPartition) {
		this.dynamicPartition = dynamicPartition;
	}

	@Override
	public void setExtExecutor(ExtExecutor extExecutor) {
		this.extExecutor = extExecutor;

		name = String.format("%s%sExtExecutor",
				new Object[]{StringTool.niceWord(extExecutor.getTo()),
						StringTool.niceWord(extExecutor.getType())});
	}

	@Override
	public ExtExecutor getExtExecutor() {
		return extExecutor;
	}

}
